package de.graph.utils;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

import org.junit.Before;
import org.junit.Test;

import de.graph.document.Document;
import de.graph.document.impl.DocumentFactory;

public class DocumentTest {

    private Document properties;
    
    @Before
    public void setUp() {
        this.properties = DocumentFactory.create();
    }
    
    @Test
    public void testDocumentOk() {
    	String name = "name";
    	Long value = 1234L;
    	
    	properties.setProperty(name, value);
    	
    	// check for object
    	assertEquals(value, properties.getProperty(name));
    }

    @Test
    public void testDocumentWrongReturnType() {
    	String name = "name";
    	Long value = 1234L;
    	
    	properties.setProperty(name, value);

    	// test for ClassCastException
    	try {
    		@SuppressWarnings("unused")
			String wrongType = properties.getProperty(name);
    		
    		fail("Expected ClassCastException!");
    	}
    	catch (ClassCastException e) {
		}
    }

    @Test
    public void testAutoBoxing() {
    	String name = "name";
    	long nativeValue = 1234L;
    	Long objectValue = Long.valueOf(nativeValue);

    	// set native value and check
    	properties.setProperty(name, nativeValue);
    	
    	assertEquals(objectValue, properties.getProperty(name));
    	assertEquals(nativeValue      , properties.getProperty(name));
    	
    	// set value object and check
    	properties.setProperty(name, objectValue);
    	
    	assertEquals(objectValue, properties.getProperty(name));
    	assertEquals(nativeValue      , properties.getProperty(name));
    }

    @Test
    public void testChangingProperty() {
    	String name = "name";
    	Long longValue = Long.valueOf(1234L);
    	String stringValue = "hallo";
    	
    	// set and check for longValue
    	properties.setProperty(name, longValue);
    	
    	assertEquals(longValue, properties.getProperty(name));

    	// set and check for stringValue
    	properties.setProperty(name, stringValue);
    	
    	assertEquals(stringValue, properties.getProperty(name));
    }

    @Test
    public void testPropertyKeys() {
    	Long longValue = Long.valueOf(1234L);
    	String stringValue = "hallo";
    	
    	// set properties
    	properties.setProperty("name1", longValue);
    	properties.setProperty("name2", stringValue);

        assertEquals(2, properties.getPropertyKeys().size());
    	for (String key : properties.getPropertyKeys()) {
			Object object = properties.getProperty(key);
			
			if (object instanceof Long) {
		    	assertEquals(longValue, object);
			}
			else {
		    	assertEquals(stringValue, object);
			}
		}
    }

    @Test
    public void testPropertyValues() {
        Long longValue = Long.valueOf(1234L);
        String stringValue = "hallo";
        
        // set properties
        properties.setProperty("name1", longValue);
        properties.setProperty("name2", stringValue);

        assertEquals(2, properties.getPropertyValues().size());
        for (Object object : properties.getPropertyValues()) {
            
            if (object instanceof Long) {
                assertEquals(longValue, object);
            }
            else {
                assertEquals(stringValue, object);
            }
        }
    }

    @Test
    public void testPropertyValuesOneType() {
        Long longValue1 = Long.valueOf(1234L);
        Long longValue2 = Long.valueOf(Long.MAX_VALUE - 1234L);
        
        // set properties
        properties.setProperty("longValue1", longValue1);
        properties.setProperty("longValue2", longValue2);

        assertEquals(2, properties.getPropertyValues().size());
        for (Long longValue : properties.getPropertyValues(Long.class)) {
            
            assertTrue(longValue instanceof Long);
        }
        
        properties.setProperty("value3", "value3");

        try {
            for (Long longValue : properties.getPropertyValues(Long.class)) {
                
                assertTrue(longValue instanceof Long);
            }
            
            fail("Expected ClassCastException!");
        }
        catch (ClassCastException e) {
            // java.lang.String cannot be cast to java.lang.Long
        }
    }
}
